﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace GetWebInfo
{
    class FinancialAnalysis
    {
        public FinancialAnalysis(SortedList<int, Statement> sifs, SharePrice sp, Split split, decimal nextYearMultiple)
        {
            this._sharePrice = sp;
            this._split = split;
            this._Statements = sifs;
            this._nextYearMultiple = nextYearMultiple;

            this._marketCapital = new MarketCapital(this._sharePrice, this._split);
        }

        [FinancialAnalysisAttribute("市销率 静态 净利润 所有价格")]
        public SortedList<DateTime, decimal> PS_Static_Net_AllValue
        {
            get
            {
                SortedList<DateTime, decimal> _retv = new SortedList<DateTime, decimal>();

                decimal _temp = 0;
                foreach (KeyValuePair<DateTime, decimal> kvp in this._marketCapital.Capitals)
                {
                    Statement _value = new Statement();
                    this._Statements.TryGetValue(kvp.Key.Year, out _value);

                    if (_value != null)
                    {
                        if (_value is IndustrialStatements)
                        {
                            _retv.Add(kvp.Key, this._quotient(kvp.Value, ((IndustrialStatements)_value).Revenue));
                            _temp = ((IndustrialStatements)_value).Revenue;
                        }
                        else
                        {
                            _retv.Add(kvp.Key, this._quotient(kvp.Value, ((FinanceStatements)_value).Revenue));
                            _temp = ((FinanceStatements)_value).Revenue;
                        }
                    }
                    else
                    {
                        //对于还没有财务报表的年份，假设其值在上一年的基础上增加10%
                        _retv.Add(kvp.Key, this._quotient(kvp.Value, _temp * 1.1M));
                    }                    
                }

                return _retv;
            }            
        }

        [FinancialAnalysisAttribute("市盈率 静态 净利润 所有价格")]
        public SortedList<DateTime, decimal> PE_Static_Net_AllValue
        {
            get
            {
                SortedList<DateTime, decimal> _retv = new SortedList<DateTime, decimal>();

                decimal _temp = 0;
                foreach (KeyValuePair<DateTime, decimal> kvp in this._marketCapital.Capitals)
                {
                    Statement _value;
                    this._Statements.TryGetValue(kvp.Key.Year, out _value);

                    if (_value != null)
                    {
                        if (_value is IndustrialStatements)
                        {
                            _retv.Add(kvp.Key, this._quotient(kvp.Value, ((IndustrialStatements)_value).Net_Profit));
                            _temp = ((IndustrialStatements)_value).Net_Profit;
                        }
                        else
                        {
                            _retv.Add(kvp.Key, this._quotient(kvp.Value, ((FinanceStatements)_value).Net_Profit));
                            _temp = ((FinanceStatements)_value).Net_Profit;
                        }
                    }
                    else
                    {
                        _retv.Add(kvp.Key, this._quotient(kvp.Value, _temp * this._nextYearMultiple));
                    }
                }

                return _retv;
            }
        }

        [FinancialAnalysisAttribute("市净率 静态 所有价格")]
        public SortedList<DateTime, decimal> PB_Static_AllValue
        {
            get
            {
                SortedList<DateTime, decimal> _retv = new SortedList<DateTime, decimal>();

                decimal _tempNetAsserts = 0;
                foreach (KeyValuePair<DateTime, decimal> kvp in this._marketCapital.Capitals)
                {
                    Statement _value;
                    decimal _jidu = Math.Ceiling((decimal.Parse(kvp.Key.Month.ToString())) / 3);
                    int _jidustr = int.Parse(string.Format("{0}{1}", kvp.Key.Year, _jidu));

                    if (this._Statements.ContainsKey(_jidustr))
                    {
                        this._Statements.TryGetValue(_jidustr, out _value);
                    }
                    else
                    {
                        this._Statements.TryGetValue(kvp.Key.Year, out _value);
                    }

                    //由于是按季度统计的PB，因此无需动态调整净资产
                    if (_value != null)
                    {
                        if (_value is IndustrialStatements)
                        {
                            _tempNetAsserts = ((IndustrialStatements)_value).Total_Owners_Equity;
                        }
                        else
                        {
                            _tempNetAsserts = ((FinanceStatements)_value).Total_Equity;
                        }
                    }
                    _retv.Add(kvp.Key, this._quotient(kvp.Value, _tempNetAsserts));
                }

                return _retv;
            }
        }

        [FinancialAnalysisAttribute("市净率*市盈率 静态 所有价格")]
        public SortedList<DateTime, decimal> PB_Multi_PE_Static_AllValue
        {
            get
            {
                SortedList<DateTime, decimal> _retv = new SortedList<DateTime, decimal>();

                SortedList<DateTime, decimal> _pe = this.PE_Static_Net_AllValue;
                SortedList<DateTime, decimal> _pb = this.PB_Static_AllValue;

                foreach (KeyValuePair<DateTime, decimal> kvp in this._marketCapital.Capitals)
                {
                    _retv.Add(kvp.Key, _pe[kvp.Key] * _pb[kvp.Key]);
                }

                return _retv;
            }
        }

        /// <summary>
        /// 盈利收益率 静态 净利润 所有价格
        /// PE的倒数
        /// </summary>
        [FinancialAnalysisAttribute("盈利收益率 静态 净利润 所有价格")]
        public SortedList<DateTime, decimal> Earnings_Yield_Static_Net_AllValue
        {
            get
            {
                SortedList<DateTime, decimal> _retv = new SortedList<DateTime, decimal>();

                SortedList<DateTime, decimal> _pe = this.PE_Static_Net_AllValue;

                foreach (KeyValuePair<DateTime, decimal> kvp in this._marketCapital.Capitals)
                {
                    _retv.Add(kvp.Key, this._quotient(1, _pe[kvp.Key]));
                }

                return _retv;
            }
        }

        /*
        /// <summary>
        /// 现金收益率 静态 净利润 所有价格
        /// FCF / 企业价值
        /// </summary>
        [FinancialAnalysisAttribute("现金收益率 静态 净利润 所有价格")]
        public SortedList<DateTime, decimal> Cash_Return_Static_Net_AllValue
        {
            get
            {
                SortedList<DateTime, decimal> _retv = new SortedList<DateTime, decimal>();

                decimal _temp = 0;
                decimal _temp2 = 0;
                decimal _temp3 = 0;
                foreach (KeyValuePair<DateTime, decimal> kvp in this._marketCapital.Capitals)
                {
                    IndustrialStatements _value;
                    this._Statement.TryGetValue(kvp.Key.Year, out _value);

                    if (_value != null)
                    {
                        _retv.Add(kvp.Key, this._quotient(_value.Net_Cash_Flows_from_Operating_Activities - _value.Cash_Paid_to_Acquire_Fixed_Assets_Intangible_Aassets_and_Other_Long_Term_Assets - _value.Net_Cash_Paid_to_Acquire_Subsidiaries_and_Other_Business_Units, (kvp.Value + _value.Long_Term_Borrowings - _value.Cash_at_Bank_and_on_Hand)));
                        _temp = _value.Net_Cash_Flows_from_Operating_Activities - _value.Cash_Paid_to_Acquire_Fixed_Assets_Intangible_Aassets_and_Other_Long_Term_Assets - _value.Net_Cash_Paid_to_Acquire_Subsidiaries_and_Other_Business_Units;
                        _temp2 = _value.Long_Term_Borrowings;
                        _temp3 = _value.Cash_at_Bank_and_on_Hand;
                    }
                    else
                    {
                        //对于还没有财务报表的年份，假设其值在上一年的基础上增加10%
                        _retv.Add(kvp.Key, this._quotient(_temp * 1.1M, (kvp.Value + _temp2 * 1.1M - _temp3 * 1.1M)));
                    }
                }

                return _retv;
            }
        }


        /// <summary>
        /// 现金收益率2 静态 净利润 所有价格
        /// FCF / 市值
        /// </summary>
        [FinancialAnalysisAttribute("现金收益率2 静态 净利润 所有价格")]
        public SortedList<DateTime, decimal> Return_on_Cash_Static_Net_AllValue
        {
            get
            {
                SortedList<DateTime, decimal> _retv = new SortedList<DateTime, decimal>();

                decimal _temp = 0;
                foreach (KeyValuePair<DateTime, decimal> kvp in this._marketCapital.Capitals)
                {
                    IndustrialStatements _value;
                    this._Statement.TryGetValue(kvp.Key.Year, out _value);

                    if (_value != null)
                    {
                        _retv.Add(kvp.Key, this._quotient(_value.Net_Cash_Flows_from_Operating_Activities - _value.Cash_Paid_to_Acquire_Fixed_Assets_Intangible_Aassets_and_Other_Long_Term_Assets - _value.Net_Cash_Paid_to_Acquire_Subsidiaries_and_Other_Business_Units, kvp.Value));
                        _temp = _value.Net_Cash_Flows_from_Operating_Activities - _value.Cash_Paid_to_Acquire_Fixed_Assets_Intangible_Aassets_and_Other_Long_Term_Assets - _value.Net_Cash_Paid_to_Acquire_Subsidiaries_and_Other_Business_Units;
                    }
                    else
                    {
                        //对于还没有财务报表的年份，假设其值在上一年的基础上增加10%
                        _retv.Add(kvp.Key, this._quotient(_temp * 1.1M, kvp.Value));
                    }
                }

                return _retv;
            }
        }        

        [FinancialAnalysisAttribute("股息率 静态 所有价格")]
        public SortedList<DateTime, decimal> Dividend_Yield_Static_AllValue
        {
            get
            {
                SortedList<DateTime, decimal> _retv = new SortedList<DateTime, decimal>();

                decimal _temp = 0;
                foreach (KeyValuePair<DateTime, decimal> kvp in this._marketCapital.Capitals)
                {
                    IndustrialStatements _value;
                    this._Statement.TryGetValue(kvp.Key.Year, out _value);

                    if (_value != null)
                    {
                        _retv.Add(kvp.Key, this._quotient(_value.Dividends, kvp.Value));
                        _temp = _value.Dividends;
                    }
                    else
                    {
                        //对于还没有财务报表的年份，假设其值在上一年的基础上增加10%
                        _retv.Add(kvp.Key, this._quotient(_temp * 1.1M, kvp.Value));
                    }
                }

                return _retv;
            }
        }
         * */


        private SortedList<int, Statement> _Statements;
        private SharePrice _sharePrice;
        private Split _split;
        private MarketCapital _marketCapital;

        //下一年指标倍数
        private decimal _nextYearMultiple;

        public MarketCapital MarketCapital
        {
            get
            {
                return this._marketCapital;
            }
        }

        /// <summary>
        /// 求两个数的商
        /// </summary>
        /// <param name="numerator">分子</param>
        /// <param name="denominator">分母</param>
        /// <returns>商</returns>
        private decimal _quotient(decimal numerator, decimal denominator)
        {
            if (denominator == 0) return 0;
            return numerator / denominator;
        }
    }

    [AttributeUsage(AttributeTargets.All)]
    public class FinancialAnalysisAttribute : Attribute
    {
        private string _Name = "";
        public string Name
        {
            get { return this._Name; }
        }

        public FinancialAnalysisAttribute(string name)
        {
            this._Name = name;
        }
    }
}
